﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Linq.Expressions;
using rusisControls.MVC.Controls.rusisGrid;

namespace rusisControls.MVC.Models
{
    public class PagedViewModel<T>
    {
        public ViewDataDictionary ViewData { get; set; }
        public IQueryable<T> Query { get; set; }
        public GridSortOptions GridSortOptions { get; set; }
        public string DefaultSortColumn { get; set; }
        //public IPagination<T> PagedList { get; private set; }
        public IList<T> DataList { get; set; } //private set
        public int? Page { get; set; }
        public int? PageSize { get; set; }
        public int? TotalCount { get; set; }

        public PagedViewModel<T> AddFilter(Expression<Func<T, bool>> predicate)
        {
            Query = Query.Where(predicate);
            return this;
        }

        public PagedViewModel<T> AddFilter<TValue>(string key, TValue value, Expression<Func<T, bool>> predicate)
        {
            ProcessQuery(value, predicate);

            if (typeof(TValue) == typeof(DateTime) || typeof(TValue) == typeof(DateTime?))
            {
                var val = (value as DateTime?).Value;
                string parseFormatString = "";
                if (val.TimeOfDay == TimeSpan.Zero)
                    parseFormatString = "dd.MM.yyyy";
                else
                    parseFormatString = "dd.MM.yyyy HH:mm:ss";

                ViewData[key] = val.ToString(parseFormatString);
            }
            else
                ViewData[key] = value;

            return this;
        }

        public PagedViewModel<T> AddFilter<TValue>(string keyField, object value, Expression<Func<T, bool>> predicate,
            IQueryable<TValue> query, string textField)
        {
            ProcessQuery(value, predicate);
            var selectList = query.ToSelectList(keyField, textField, value);
            ViewData[keyField] = selectList;
            return this;
        }

        public PagedViewModel<T> Setup()
        {
            if (string.IsNullOrEmpty(DefaultSortColumn))
                DefaultSortColumn = "Id";

            if (GridSortOptions == null)
                GridSortOptions = new GridSortOptions() { Column = DefaultSortColumn, Direction = SortDirection.Ascending };

            if (string.IsNullOrWhiteSpace(GridSortOptions.Column))
            {
                GridSortOptions.Column = DefaultSortColumn;
            }

            // Установка общего количества записей в БД
            TotalCount = Query.Count();

            // Установка номера страницы, если он не был ранее установлен
            if (Page == null || Page <= 0)
                Page = 1;

            // Установка количества строк на странице, если оно не был ранее установлено
            if (PageSize == null || PageSize <= 0)
                PageSize = 10;


            //PagedList = Query.OrderBy(GridSortOptions.Column, GridSortOptions.Direction)
            //    .AsPagination(Page ?? 1, PageSize ?? 10);

            int totalRecords;
            //PagedList = Query.Page<T, IQueryable<T>>(
            //        Page ?? 1, 
            //        PageSize ?? 10, 
            //        GridSortOptions.Column, 
            //        (GridSortOptions.Direction == SortDirection.Ascending ? true : false),
            //        out totalRecords)
            //    .AsPagination(Page ?? 1, PageSize ?? 10);
            //DataList = PagedList.ToList();

            DataList = Query.Page<T, IQueryable<T>>(
                    Page ?? 1,
                    PageSize ?? 10,
                    GridSortOptions.Column,
                    (GridSortOptions.Direction == SortDirection.Ascending ? true : false),
                    out totalRecords).ToList();

            return this;
        }

        private void ProcessQuery<TValue>(TValue value, Expression<Func<T, bool>> predicate)
        {
            if (value == null) return;
            if (typeof(TValue) == typeof(string))
            {
                if (string.IsNullOrWhiteSpace(value as string)) return;
            }
            Query = Query.Where(predicate);
        }
    }
}
